/**
 * @(#)ChannelTaskServiceImpl.java 2016年11月8日
 * Copyright(C) 2016 ZHEXIN IT CO.,LTD. All rights reserved.
 */
package org.jsbd.boss.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qy.recphone.service.IRecPhoneService;
import edu.hziee.common.queue.DelayExecuteBuffer;
import org.apache.commons.lang.StringUtils;
import org.jsbd.boss.bto.*;
import org.jsbd.boss.common.ConstantsCmp;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.domian.*;
import org.jsbd.boss.domian.channel.*;
import org.jsbd.boss.enums.*;
import org.jsbd.boss.mq.KafkaMqManager;
import org.jsbd.boss.mq.LogProcessor;
import org.jsbd.boss.mq.UserLogManager;
import org.jsbd.boss.service.*;
import org.jsbd.boss.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
 * @version 1.0.0
 */
@Service
public class ChannelTaskServiceImpl implements IChannelTaskService {
    public static final Logger logger = LoggerFactory.getLogger(ChannelTaskServiceImpl.class);
    @Resource(name = "newTaskService")
    private INewTaskService newTaskService;

    @Resource(name = "retentTaskService")
    private IRetentTaskService retentTaskService;

    @Resource
    private SimulatorManager simulatorManager;
    @Resource
    private ClientManager clientManager;

    @Resource
    private IUserClientInfoService userClientInfoService;

    @Resource
    private ApkManager apkManager;

    @Resource
    private IProvinceService provinceService;
    @Resource
    private IClientLoginService clientLoginService;

    @Resource
    private IInterceptInfoService interceptInfoService;
    @Resource
    private IChannelApkInfoService channelApkInfoService;
    @Resource
    private IRecPhoneService recPhoneService;

    @Resource
    private DelayExecuteBuffer<SmsRecord> thirdSmsRecordBuffer;

    @Resource
    private RedisClient redisClient;
    @Resource
    private ISimulatorLogService simulatorLogService;

    @Resource
    private CacheParamManager cacheParamManager;

    // 发送号码
    private static final String PHONE_NUM = PropertiesUtil.getValue("dmlogin_phone", "106581061");

    // 发送号码
    private static final String IS_SYNC_PHONENUM = PropertiesUtil.getValue("is_sync_phonenum", "off");

    @Resource
    private IThirdTaskService thirdTaskService;

    @Resource
    private LogManager logManager;


    /*
     * (non-Javadoc)
     *
     * @see org.jsbd.boss.task.ChannelTaskService#getTask(org.jsbd.boss.task.vo.
     * DeviceInfoVo)
     */
    @Override
    public BaseResultVo getTask(SimulatorInfoVo simulator) throws Exception {
        BaseResultVo baseResultVo = new BaseResultVo();
        String task = redisClient.evalRpop(CacheKey.VER_TASK_QUEUE + simulator.getSysVer());
        if (StringUtils.isBlank(task)) {
            baseResultVo.setStatus(ResponseEnum.FAIL.getStatus());
            baseResultVo.setMessage("没有可用任务!");
            simulator.setBusy(false);
            //测试使用
            if (simulator.isTest()) {
                boolean newSimulator = apkManager.checkNewSimulator(simulator.getSysVer());
                if (newSimulator) {
                    task = redisClient.evalRpop(CacheKey.NEW_SDK_QUEUE + simulator.getSysVer());
                }
            }
        }
        if (StringUtils.isNotBlank(task)) {
            task = execTaskExtendsAction(task, simulator.getUuid());
            if (task == null) {
                baseResultVo.setStatus(ResponseEnum.FAIL.getStatus());
                simulator.setBusy(false);
            } else {
                baseResultVo.setStatus(ResponseEnum.SUCC.getStatus());
                simulator.setBusy(true);
            }
            baseResultVo.setData(task);
        }
        // 将模拟器请求信息发送到MQ
        KafkaMqManager.simulatorReqToQueue(simulator);
        KafkaMqManager.reqTaskTimeToQueue(task);
        // 注册模拟器
        simulatorManager.addSimulator(simulator);
        return baseResultVo;
    }

    @Override
    public BaseResultVo smsTask(String result) throws Exception {
        HttpResult httpResult = new HttpResult();
        try {
            JSONObject jsonObject = JSONObject.parseObject(result);
            httpResult = TaskUtil.initHttpResult(jsonObject);
        } catch (Exception e) {
            logger.error("json解析出错", e);
        }
        return sendSms(httpResult);
    }

    /**
     * execTaskExtendsAction:获取任务扩展操作
     *
     * @param task
     * @return
     * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
     */
    private String execTaskExtendsAction(String task, String uuid) {
        JSONObject dataObj = null;
        dataObj = JSONObject.parseObject(task);
        String imsi = dataObj.getString("imsi");
        dataObj.put("serversystime", String.valueOf(System.currentTimeMillis()));
        Object taskType = dataObj.get("taskType");
        String mark = dataObj.getString("mark");
        if (taskType != null) {
            if (taskType.toString().equals("1")) {
                Object sysTime = dataObj.get("systime");
                if (sysTime != null) {
                    long systime = Long.parseLong(sysTime.toString());
                    long time = System.currentTimeMillis() - systime;
                    if (time > 60000) {
                        logManager.printLog(logger, "新增任务 apk {} loginType {} imsi {} 时间 {} 秒, 大于60秒", new Object[]{mark, dataObj.get("loginType"), imsi, time / 1000});
                        Object loginType = dataObj.get("loginType");
                        if (loginType != null && (String.valueOf(LoginTypeEnum.SELF_CARD.getType()).equals(loginType.toString()) || String.valueOf(LoginTypeEnum.SELF_MAO.getType()).equals(loginType.toString()))) {
                            String apkExecTotal = CacheKey.APK_LOGIN_KEY + DateUtil.getDaysOfTime() + mark;
                            String apkLoginExecTotal = CacheKey.A_TASK + DateUtil.getDaysOfTime() + mark;
                            String loginExecTotal = loginType + "exectotal";
                            redisClient.evalHincrby(apkExecTotal, "exectotal", -1);
                            redisClient.evalHincrby(apkLoginExecTotal, loginExecTotal, -1);
                            return null;
                        }
                    }
                }
            }
            task = dataObj.toJSONString();
            addGetTaskLog(task, Integer.parseInt(taskType.toString()), uuid, dataObj.getString("hostAndPort"));
        }
        String brushId = dataObj.getString("brushId");
        LogProcessor.getTM().addIssuedTaskLog(DateUtil.getCurrentDateStr(), mark,imsi, taskType, brushId);
        return task;
    }

    /**
     * @param task
     * @param taskType
     * @param uuid
     * @param hostAndPort
     */
    private void addGetTaskLog(String task, Integer taskType, String uuid, String hostAndPort) {
        if (StringUtils.isNotBlank(task)) {
            try {
                DMClientInfo clientInfo = clientManager.initClientInfo(task);
                clientInfo.setStatus(TaskStatusEnum.SUCCESS.getType());
                clientInfo.setTaskType(taskType);
                if (taskType == TaskTypeEnum.ADD_TASK.getType()) {
                    logManager.printLog(logger, "模拟器获取到新增任务为 {} {} {}", new String[]{uuid, clientInfo.getMark(), task});
                } else if (taskType == TaskTypeEnum.RETENT_TASK.getType()) {
                    logManager.printLog(logger, "模拟器获取到留存任务为 {} {} {}", new String[]{uuid, clientInfo.getMark(), task});
                }
                if (clientInfo.getImsi() == null) {
                    clientInfo.setImsi("0000");
                }
                clientInfo.setActionType(TaskActionEnum.GET_TASK.getType());
                clientInfo.setUuid(uuid);
                clientInfo.setHostAndPort(hostAndPort);
                // 获取任务日志
                simulatorLogService.addSimulatorLog(clientInfo);
            } catch (Exception e) {
                logger.error("添加日志异常", e);
            }
        } else {
            logManager.printLog(logger, "模拟器没有获取到任务 uuid {} type {}", new Object[]{uuid, taskType});
        }
    }


    /*
     * (non-Javadoc)
     *
     * @see org.jsbd.boss.task.ChannelTaskService#syncSmsTask(java.lang.String,
     * java.lang.String)
     */
    @Override
    public BaseResultVo syncSmsTask(String orderId, String resultCode) throws Exception {
        BaseResultVo result = new BaseResultVo();
        int index = orderId.indexOf("_");
        String imsi = orderId.substring(0, index);
        String mark = orderId.substring(index + 1);
        DMClientInfo clientInfo = clientManager.getClientOfSdk(imsi);
        ChannelApkConfig apkConfig = channelApkInfoService.selectChannelApkConfig(mark);
        boolean hasLogined = clientManager.hasLogined(imsi, apkConfig.getId(), apkConfig.getBase());
        if (!hasLogined) {
            clientInfo.setMark(mark);
            clientInfo.setActionType(TaskActionEnum.SYNC_SMS_TASK.getType());
            clientInfo.setLoginType(LoginTypeEnum.SDK.getType());
            clientInfo.setTaskType(TaskTypeEnum.ADD_TASK.getType());
            clientInfo.setCurrentDate(DateUtil.getCurrentDateStr());
            clientInfo.setOrderId(orderId);
            clientInfo.setResultCode(resultCode);
            clientInfo.setBase(apkConfig.getBase());
            if (StringUtils.isNotBlank(resultCode) && "0".equals(resultCode)) {
                NewUserTaskVo taskVo = new NewUserTaskVo();
                BeanCopierUtil.DmClient2newTaskBeanCopier.copy(clientInfo, taskVo, null);
                taskVo.setBase(apkConfig.getBase());
                taskVo.setApkId(apkConfig.getId());
                taskVo.setAddScriptPath(apkConfig.getAddScriptPath());
                taskVo.setApkPath(apkConfig.getApkPath());
                taskVo.setAddJarPath(apkConfig.getAddJarPath());
                taskVo.setRegisterActivity(apkConfig.getRegisterActivity());
                taskVo.setFileFilter(apkConfig.getFileFilter());
                taskVo.setMark(mark);
                taskVo.setLogLevel(apkConfig.getLogLevel());
                List<ApkLoginTypeConfig> loginConfigList = apkManager.getOnlineLoginTypeMap().get(mark);
                for (ApkLoginTypeConfig loginConfig : loginConfigList) {
                    if (loginConfig.getLoginType().intValue() == LoginTypeEnum.SDK.getType()) {
                        taskVo.setPayMax(loginConfig.getPayMax());
                        taskVo.setPayMin(loginConfig.getPayMin());
                        taskVo.setPayRate(loginConfig.getPayRate());
                    }
                }
                TaskStatusEnum taskStatusEnum = newTaskService.addTask(taskVo);
                if (taskStatusEnum == TaskStatusEnum.SUCCESS) {
                    clientInfo.setStatus(TaskStatusEnum.SUCCESS.getType());
                } else {
                    clientManager.updateSuccTimesOfImsi(imsi);
                    clientInfo.setStatus(taskStatusEnum.getType());
                    result.setStatus(ResponseEnum.FAIL.getStatus());
                    result.setMessage("用户同步短信不成功,队列已经满了或者已经同步过了!");
                    logManager.printLog(logger, "用户 [{}]，apk [{}] 添加任务不成功,短信发送结果为{}", new Object[]{clientInfo.getImsi(), clientInfo.getMark(), resultCode});
                }
            } else {
                result.setStatus(ResponseEnum.FAIL.getStatus());
                result.setMessage("用户" + orderId + "同步短信不成功,短信发送未成功!");
                clientInfo.setStatus(ResponseEnum.FAIL.getStatus());
                clientManager.updateFailTimesOfImsi(imsi);
                logManager.printLog(logger, "用户 [{}]，apk [{}] 同步短信不成功,短信发送结果为{}", new Object[]{clientInfo.getImsi(), clientInfo.getMark(), resultCode});
            }
            simulatorLogService.addSimulatorLog(clientInfo);
            KafkaMqManager.syncSmsToQueue(clientInfo);
        } else {
            logManager.printLog(logger, "用户 [{}] apk[{}]已经同步过短信", new Object[]{clientInfo.getImsi(), clientInfo.getMark()});
            result.setStatus(ResponseEnum.FAIL.getStatus());
            result.setMessage("用户[" + orderId + "]已经同步过短信!");
        }
        return result;
    }


    /**
     * 无效用户返回false
     *
     * @param httpResult
     * @return
     */
    private boolean checkHttpResult(HttpResult httpResult) {

        String imsi = httpResult.getImsi();
        String imei = httpResult.getImei();
        String hsman = httpResult.getHsman();
        String hstype = httpResult.getHstype();
        String sdkVerName = httpResult.getSdkVerName();

        if (StringUtils.isBlank(imsi)
                || imsi.length() != 15
                || !clientManager.isRightImei(imei)
                || StringUtils.isBlank(hsman)
                || StringUtils.isBlank(hstype)
                || StringUtils.isBlank(sdkVerName)) {
            logManager.printLog(logger, "用户参数错误 imsi {} imei {} hsman {} hstype {} sdkVerName {} ", new String[]{imsi, imei, hsman, hstype, sdkVerName});
            return false;
        }
        Integer carrier = ClientManager.checkImsi(imsi);
        if (carrier == -1) {
            logManager.printLog(logger, "imsi {} 找不到对应的运营商", new Object[]{imsi});
            return false;
        }

        String fingerprint = httpResult.getFingerprint();
        if (StringUtils.isNotBlank(fingerprint) && fingerprint.contains("userdebug")) {
            return false;
        }
        boolean isNew = clientManager.isNewSdkVersion(sdkVerName);
        //不是新用户不做参数校验
        if (!isNew) {
            if (StringUtils.isBlank(httpResult.getCpuSerial())) {
                httpResult.setCpuSerial("0000000000000000");
            }
            if (StringUtils.isBlank(httpResult.getKernelVersion())) {
                httpResult.setKernelVersion("Linux version 3.10.28-g76d2478 (jenkins@SIA1000017825) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT " + new Date());
            }
            if (StringUtils.isBlank(httpResult.getNetworkExtraInfo())) {
                String networkExtraInfo = "TP-LINK_" + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4).toUpperCase();
                httpResult.setNetworkExtraInfo(networkExtraInfo);
            }
            return true;
        }

        Boolean isFilter = (Boolean) redisClient.getHash(CacheKey.ONLINE_USER_FILTER, imsi);
        if (isFilter != null) {
            return isFilter;
        }
        isFilter = true;
        try {
            String sdkUuid = "sdkFile/" + httpResult.getUuid() + "/newSo";
            byte[] newSo = OssUtils.downloadWebmengFile(sdkUuid);
            String so = new String(newSo, "utf-8");
            JSONObject soObj = JSONObject.parseObject(so);
            JSONArray riskfile = soObj.getJSONArray("riskfile");
            if (riskfile != null) {
                for (Object obj : riskfile) {
                    JSONObject riskObj = (JSONObject) obj;
                    String key = riskObj.getString("key");
                    String value = riskObj.getString("h");
                    if ("iomem".equals(key) || "ioports".equals(key) || "misc".equals(key)) {
                        if (StringUtils.isNotBlank(value) && !"[]".equals(value)) {
                            isFilter = false;
                        }
                    } else if ("kallsyms".equals(key)) {
                        if (StringUtils.isNotBlank(value) && value.contains("vbox")) {
                            isFilter = false;
                        }
                    }
                }
            }
        } catch (Exception e) {
            logManager.printLog(logger, "用户so文件解析失败 {} {} {}", new Object[]{imsi, httpResult.getUuid(), e});
            return true;
        }

        if (!isFilter) {
            logManager.printLog(logger, "过滤掉的用户 {} {}", new Object[]{imsi, httpResult.getUuid()});
        }
        redisClient.putHash(CacheKey.ONLINE_USER_FILTER, imsi, isFilter);
        return isFilter;

    }

    /**
     * sendSms:发短信
     *
     * @param httpResult
     * @return
     * @throws Exception
     * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
     */
    @Override
    public BaseResultVo sendSms(HttpResult httpResult) throws Exception {
        UserLogManager.addUserReq(httpResult);
        BaseResultVo result = new BaseResultVo();
        boolean valitor = checkHttpResult(httpResult);
        if (!valitor) {
            logManager.printLog(logger, "当前用户参数有问题 {} {}", new Object[]{httpResult.getImsi(), httpResult.getUuid()});
            result.setStatus(TaskStatusEnum.SDK_INFO_EMPTY.getType());
            result.setMessage(TaskStatusEnum.SDK_INFO_EMPTY.getName());
            return result;
        }

        String imsi = httpResult.getImsi();
        IpRange ipRange = provinceService.getProvinceInfo(imsi, httpResult.getPhoneNum());
        Integer provinceId = ipRange.getProvinceId();
        if (provinceId == null) {
            provinceId = -1;
        }
        logManager.printLog(logger, "获取省份信息 {} {} {} {}", new String[]{imsi, String.valueOf(provinceId), httpResult.getPhoneNum(), ipRange.getPhoneNum()});
        httpResult.setPhoneNum(ipRange.getPhoneNum());
        userClientInfoService.addUserclient(httpResult, ipRange);
        result = thirdTaskService.addTask(httpResult, provinceId);
        if (result.getStatus() == ResponseEnum.SUCC.getStatus()) {
            UserLogManager.addThirdSuccLog(httpResult);
            return result;
        }
        ApkLoginTypeConfig apkLoginConfig = apkManager.selectOnlineApkProvince(imsi, provinceId, httpResult);
        if (apkLoginConfig == null) {
            result.setStatus(TaskStatusEnum.NONE_USEFUL_APK.getType());
            result.setMessage(TaskStatusEnum.NONE_USEFUL_APK.getName());
            return result;
        }
        String mark = apkLoginConfig.getMark();
        ChannelApkConfig apkConfig = channelApkInfoService.selectChannelApkConfig(mark);
        DMClientInfo clientInfo = clientManager.initClientInfo(httpResult, ipRange);
        if (clientInfo == null) {
            result.setStatus(TaskStatusEnum.SDK_INFO_EMPTY.getType());
            result.setMessage(TaskStatusEnum.SDK_INFO_EMPTY.getName());
            logManager.printLog(logger, "用户信息错误 imsi {} imei {},sdkVersion {}", new String[]{imsi, httpResult.getImei(), httpResult.getSdkVerName()});
            return result;
        }
        clientInfo.setMark(mark);
        TaskVo taskVo = TaskUtil.initTaskVo(clientInfo, apkConfig);
        TaskStatusEnum taskStatus = clientLoginService.sendSms(taskVo, apkLoginConfig);
        if (taskStatus == TaskStatusEnum.SUCCESS) {
            UserLogManager.addBizSuccLog(httpResult);
            clientInfo.setNetworkType(taskVo.getNetworkType());
            if (apkLoginConfig.getLoginType() == LoginTypeEnum.SDK.getType()) {
                clientManager.recordSdkClient(clientInfo);
            } else if (apkLoginConfig.getLoginType() == LoginTypeEnum.SMS_CODE.getType()) {
                clientInfo.setAppName(null);
                clientInfo.setSystemAppName(null);
                clientManager.recordNoSdkClient(clientInfo);
            }
            SmsProtocol data = createSdkSms(apkLoginConfig.getLoginType(), apkConfig, clientInfo);
            result.setData(data);
            clientInfo.setStatus(ResponseEnum.SUCC.getStatus());
            clientInfo.setActionType(TaskActionEnum.SEND_TASK.getType());
            clientInfo.setLoginType(apkLoginConfig.getLoginType());
            clientInfo.setTaskType(TaskTypeEnum.ADD_TASK.getType());
            clientInfo.setBase(apkConfig.getBase());
            clientInfo.setLoginCode(data == null ? null : data.toString());
            simulatorLogService.addSimulatorLog(clientInfo);
        }
        result.setMessage(mark + taskStatus.getName());
        result.setStatus(taskStatus.getType());
        logManager.printLog(logger, "用户请求发送短信的结果为 {} {} ", new Object[]{imsi, result.getMessage()});
        return result;
    }

    /**
     * @param loginType
     * @param apkConfig
     * @param clientInfo
     * @return
     * @throws Exception
     */
    private SmsProtocol createSdkSms(Integer loginType, ChannelApkConfig apkConfig, DMClientInfo clientInfo) throws Exception {
        String imsi = clientInfo.getImsi();
        if (loginType == LoginTypeEnum.SDK.getType()) {
            // 产生短信 设置客户端信息
            String loginCode = clientLoginService.getLoginCode(apkConfig, clientInfo);
            SmsProtocol data = getSmsProtocol(loginCode, "1", apkConfig, imsi);
            logManager.printLog(logger, "发送短信 imsi {} sms {} checkSms {} ", new String[]{imsi, loginCode, data.toString()});
            return data;
        } else if (loginType == LoginTypeEnum.SMS_CODE.getType()) {
            SmsProtocol data = getSmsProtocol(null, "0", apkConfig, imsi);
            logManager.printLog(logger, "发送短信 imsi {}  checkSms {} ", new String[]{imsi, data.toString()});
            return data;
        } else {
            return null;
        }
    }

    /**
     * @param message
     * @param needSendSms
     * @param apkConfig
     * @param imsi
     * @return
     */
    private SmsProtocol getSmsProtocol(String message, String needSendSms, ChannelApkConfig apkConfig, String imsi) {
        SdkSmsVo smsVo = new SdkSmsVo();
        String orderId = imsi + "_" + apkConfig.getMark();
        smsVo.setPhone(PHONE_NUM);
        Integer sendType = apkConfig.getSendType();
        smsVo.setSendType(sendType.toString());
        if (sendType == SmsSendTypeEnum.TEXT.getType()) {
            smsVo.setMessage(message);
            smsVo.setSendPort("0");
        } else {
            smsVo.setSendPort("2000");
            if (message != null) {
                smsVo.setMessage(AndroidBase64.encode(message.getBytes()));
            }
        }
        List<InterceptInfo> inteceptList = interceptInfoService.selectInterceptOfIds(apkConfig.getMark(), apkConfig.getInterceptId());

        TVerifyInfo verifyInfo = new TVerifyInfo();
        if (inteceptList != null && inteceptList.size() > 0) {
            Iterator<InterceptInfo> iterator = inteceptList.iterator();
            List<TVerifyInfo> verifyInfoList = new ArrayList<TVerifyInfo>();
            while (iterator.hasNext()) {
                InterceptInfo info = iterator.next();
                Integer reply = info.getNeedReply();
                if (reply != null && reply == 1) {
                    verifyInfo.setPloyMatch(info.getMsgContent());
                    verifyInfo.setCode(info.getReplyContent());
                    verifyInfo.setRegexVerify(info.getRegexContent());
                    // 固定回复内容 这个先做成这样
                    verifyInfo.setReplyType(1);
                    verifyInfoList.add(verifyInfo);
                    iterator.remove();
                }
            }
            smsVo.setVerifyInfo(verifyInfoList);
            smsVo.setInteceptList(inteceptList);
        }
        smsVo.setSendCount("1");
        smsVo.setReSendCount("0");
        smsVo.setNeedSendSms(needSendSms);
        smsVo.setPaycode(apkConfig.getMark());
        HttpReq hReq = DMChannelSmsUtil.flushChannel(ConstantsCmp.PROTOCOL_TYPE_SMS, orderId, smsVo);
        List<HttpReq> taskList = new ArrayList<HttpReq>();
        taskList.add(hReq);
        return DMChannelSmsUtil.wrapSmsProtocol(taskList);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.jsbd.boss.service.IChannelTaskService#syncRetentTask(org.jsbd.boss
     * .domian.channel.RetentTaskVo)
     */
    @Override
    public BaseResultVo syncRetentTask(RetentTaskVo taskInfo) throws Exception {
        BaseResultVo baseResultVo = new BaseResultVo();
        boolean result = retentTaskService.syncTask(taskInfo);
        // 20170316 同步手机号码
        if ("on".equals(IS_SYNC_PHONENUM)) {
            try {
                savePhoneNum(taskInfo);
            } catch (Exception e) {
                logger.error("同步手机号码出错", e);
            }
        }

        if (!result) {
            baseResultVo.setStatus(ResponseEnum.FAIL.getStatus());
            baseResultVo.setMessage("同步留存任务失败！");
        }
        return baseResultVo;
    }

    /**
     * @param smsVo
     * @return
     * @throws Exception
     */
    @Override
    public BaseResultVo syncSmsTask(SmsSyncVo smsVo) throws Exception {
        String sms = smsVo.getSms();
        String orderId = smsVo.getOrderId();
        String resultCode = smsVo.getResultCode();
        if (StringUtils.isNotBlank(sms)) {
            String bizId = smsVo.getBizId();
            if (StringUtils.isNotBlank(bizId)) {
                String mark = (String) cacheParamManager.getParamValue(bizId);
                orderId = smsVo.getImsi() + "_" + mark;
                sms = smsVo.getSmsContent();
            } else if (orderId.contains(CacheKey.HEFEN) || orderId.contains("third")) {
                return syncThirdSmsCode(orderId, resultCode, sms);
            }
            return syncSmsCode(orderId, resultCode, sms);
        } else {
            if (orderId.contains("third")) {
                //第三方的短信 走sdk同步的过滤
                return new BaseResultVo();
            } else {
                return syncSmsTask(orderId, resultCode);
            }
        }
    }

    /**
     * syncHefenSmsCode:TODO 请描述该方法是做什么用途的
     *
     * @param orderId
     * @param sms
     * @return
     * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
     */
    private BaseResultVo syncThirdSmsCode(String orderId, String resultCode, String sms) {
        BaseResultVo result = new BaseResultVo();
        String imsi = null;
        String apk = null;
        if (StringUtils.isBlank(orderId) || StringUtils.isBlank(resultCode) || StringUtils.isBlank(sms)) {
            result.setStatus(ResponseEnum.FAIL.getStatus());
            result.setMessage("参数错误！");
            return result;
        } else {
            int index = orderId.indexOf("_");
            if (index > 0) {
                imsi = orderId.substring(0, index);
                apk = orderId.substring(index + 1);
                if (StringUtils.isBlank(imsi) || StringUtils.isBlank(sms)) {
                    result.setStatus(ResponseEnum.FAIL.getStatus());
                    result.setMessage("参数错误！");
                    return result;
                }
            } else {
                result.setStatus(ResponseEnum.FAIL.getStatus());
                result.setMessage("参数错误！");
                return result;
            }
        }
        logManager.printLog(logger, "用户 {} apk {} 同步短信  结果为 {} {}", new Object[]{imsi, apk, resultCode, sms});
        recordThirdSmsLog(apk, sms, resultCode, imsi);
        if (StringUtils.isNotBlank(resultCode) && "0".equals(resultCode)) {
            if (apk.indexOf(CacheKey.HEFEN) >= 0) {
                String smsId = (String) cacheParamManager.getParamValue(CacheKey.HEFEN_SMSID);
                if (smsId != null) {
                    InterceptInfo interceptInfo = interceptInfoService.selectInterceptOfId(smsId.toString());
                    String smsCode = getSmsCode(sms, interceptInfo.getRegexContent(), interceptInfo.getMsgContent());
                    if (StringUtils.isNotBlank(smsCode)) {
                        clientManager.recordImsiSmsCode(imsi, apk, smsCode);
                        return result;
                    }
                }
            } else {
                ThirdSmsSyncVo smsConfig = (ThirdSmsSyncVo) cacheParamManager.getParamValue(apk);
                if (smsConfig != null) {
                    String smsCode = getSmsCode(sms, smsConfig.getRegexContent(), smsConfig.getMsgContent());
                    if (StringUtils.isNotBlank(smsCode)) {
                        Integer taskType = smsConfig.getTaskType();
                        // 需要发短信的任务
                        if (taskType != null && taskType == 1) {
                            String syncLock = CacheKey.T_S_M_R + apk + imsi + "sync";
                            boolean exists = redisClient.evalSetNx(syncLock, 300);
                            if (!exists) {
                                logManager.printLog(logger, "用户 {} apk {} 同步短信已经同步过 {} {}", new Object[]{imsi, apk, resultCode, sms});
                                return result;
                            }
                            String key = CacheKey.THIRD_TASK_HASH + smsConfig.getCode() + DateUtil.getDaysOfTime();
                            redisClient.evalHincrby(key, "succexectotal", 1);
                        }

                        String mobile = (String) redisClient.get(CacheKey.IMSI_MOBILE + imsi);
                        smsConfig.setSmsCode(smsCode);
                        smsConfig.setImsi(imsi);
                        smsConfig.setMobile(mobile);
                        IpRange province = provinceService.getProvinceInfo(imsi, mobile);
                        if (province != null) {
                            smsConfig.setProvinceId(province.getProvinceId());
                        } else {
                            smsConfig.setProvinceId(-1);
                        }
                        String callBackUrl = smsConfig.getCallbackUrl();
                        if (StringUtils.isNotBlank(callBackUrl)) {
                            redisClient.putToQueue(CacheKey.THIRD_SMS_CALLBACK_LIST, smsConfig);
                        } else {
                            clientManager.recordImsiSmsCode(imsi, apk, smsCode);
                        }
                        SmsRecord vo = new SmsRecord();
                        vo.setImsi(imsi);
                        vo.setCode(smsConfig.getCode());
                        vo.setVerifyCode(smsCode);
                        vo.setActionType(2);
                        if (smsConfig.getCode().equalsIgnoreCase("thirdmiguregister")) {
                            String miguRecord = CacheKey.MIGU_REGISTER_REOCRD;
                            redisClient.putHash(miguRecord, imsi, "1");
                        }
                        thirdSmsRecordBuffer.add(vo);
                        return result;
                    }
                }
            }
        }
        result.setStatus(ResponseEnum.FAIL.getStatus());
        result.setMessage("用户" + orderId + "同步短信不成功,短信发送未成功!");
        return result;

    }

    private void recordThirdSmsLog(String apk, String sms, String resultCode, String imsi) {
        DMClientInfo clientInfo = new DMClientInfo();
        clientInfo.setMark(apk);
        clientInfo.setActionType(TaskActionEnum.SYNC_SMS_TASK.getType());
        clientInfo.setLoginType(LoginTypeEnum.SMS_CODE.getType());
        clientInfo.setTaskType(TaskTypeEnum.ADD_TASK.getType());
        clientInfo.setCurrentDate(DateUtil.getCurrentDateStr());
        clientInfo.setLoginCode(sms);
        clientInfo.setImsi(imsi);
        if (StringUtils.isNotBlank(resultCode) && "0".equals(resultCode)) {
            clientInfo.setStatus(1);
        } else {
            clientInfo.setStatus(0);
        }
        simulatorLogService.addSimulatorLog(clientInfo);
    }

    /**
     * getSmsCode:提取短信中的验证码
     *
     * @param msg
     * @param regexContent
     * @return
     * @author <a href="mailto:zhangbinghua@zhexinit.com" >zbh</a>
     */
    public static String getSmsCode(String msg, String regexContent, String msgContent) {
        String matchMsg = "";
        try {
            if (msg.contains(msgContent.trim())) {
                if (StringUtils.isNotBlank(regexContent)) {
                    Pattern pattern = Pattern.compile(regexContent);
                    Matcher matcher = pattern.matcher(msg);
                    if (matcher.find()) {
                        matchMsg = matcher.group(1);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("验证码", e);
        }
        return matchMsg;
    }

    /**
     * syncSmsCode:同步短信内容
     *
     * @param sms
     * @return
     * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
     */
    @Override
    public BaseResultVo syncSmsCode(String orderId, String resultCode, String sms) {
        BaseResultVo result = new BaseResultVo();
        int index = orderId.indexOf("_");
        String imsi = orderId.substring(0, index);
        String mark = orderId.substring(index + 1);
        logManager.printLog(logger, "用户 {} apk {} 同步短信  结果为 {} {}", new Object[]{imsi, mark, resultCode, sms});
        DMClientInfo clientInfo = clientManager.getNoSdkClientOfLogin(imsi);
        ChannelApkConfig apkConfig = channelApkInfoService.selectChannelApkConfig(mark);
        clientInfo.setMark(mark);
        clientInfo.setResultCode(resultCode);
        if (StringUtils.isNotBlank(resultCode) && "0".equals(resultCode)) {
            boolean succ = false;
            List<InterceptInfo> inteceptList = interceptInfoService.selectInterceptOfIds(mark, apkConfig.getInterceptId());
            for (InterceptInfo interceptInfo : inteceptList) {
                String smsCode = getSmsCode(sms, interceptInfo.getRegexContent(), interceptInfo.getMsgContent());
                if (StringUtils.isNotBlank(smsCode)) {
                    clientManager.recordImsiSmsCode(imsi, mark, smsCode);
                    succ = true;
                    break;
                }
            }
            clientInfo.setActionType(TaskActionEnum.SYNC_SMS_TASK.getType());
            clientInfo.setLoginType(LoginTypeEnum.SMS_CODE.getType());
            clientInfo.setTaskType(TaskTypeEnum.ADD_TASK.getType());
            clientInfo.setCurrentDate(DateUtil.getCurrentDateStr());
            clientInfo.setOrderId(orderId);
            if (succ) {
                clientInfo.setStatus(TaskStatusEnum.SUCCESS.getType());
            } else {
                clientManager.updateSuccTimesOfImsi(imsi);
                clientInfo.setStatus(TaskStatusEnum.FAIL.getType());
                result.setStatus(ResponseEnum.FAIL.getStatus());
                result.setMessage("用户" + orderId + "解析短信验证码不成功!");
            }
        } else {
            result.setStatus(ResponseEnum.FAIL.getStatus());
            result.setMessage("用户" + orderId + "同步验证码不成功,短信发送未成功!");
            clientInfo.setStatus(ResponseEnum.FAIL.getStatus());
            clientManager.updateFailTimesOfImsi(imsi);
            logManager.printLog(logger, "用户 [{}]，apk [{}] 同步验证码不成功,短信发送结果为 {}", new Object[]{clientInfo.getImsi(), clientInfo.getMark(), sms});
        }
        clientInfo.setBase(apkConfig.getBase());
        clientInfo.setLoginCode(sms);
        simulatorLogService.addSimulatorLog(clientInfo);
        KafkaMqManager.syncSmsToQueue(clientInfo);
        return result;
    }

    /**
     * savePhoneNum: 手机号码入库
     *
     * @param taskInfo
     * @author <a href="mailto:zhangbinghua@zhexinit.com" >zbh</a>
     */
    private void savePhoneNum(RetentTaskVo taskInfo) {
        String mobile = taskInfo.getMobile();
        String imsi = taskInfo.getImsi();
        if (StringUtils.isNotBlank(mobile) && StringUtils.isNotBlank(imsi) && mobile.length() > 10) {
            recPhoneService.savePhoneAndProvince(mobile, imsi);
        }

    }

    /*
     * (non-Javadoc)
     *
     * @see org.jsbd.boss.service.IChannelTaskService#removeImsiRecord(java.lang.
     * String)
     */
    @Override
    public void removeImsiRecord(String imsi) {
        redisClient.remove(CacheKey.A_IMSI + imsi);
    }
}
